Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiCode/Block] Avoid recomputing code syntax colors #7486

Conversation

eokoneyo
Copy link
Contributor

@eokoneyo eokoneyo commented Jan 25, 2024

Summary

Hi Friends 👋🏾

This PR results from elastic/kibana#174290 (comment). On looking into this I realized that a contributing factor to the delay in the rendering of the component happens because multiple calls are made to euiCodeSyntaxTokens, which in turn calls the method euiCodeSyntaxColors, within this method the colors for the tokens get recomputed every time. This change applies memoization to the euiCodeSyntaxColors function so that when the colour determinant hasn't changed we return the already computed result.

Before

Screenshot 2024-01-25 at 11 26 56

After

Screenshot 2024-01-25 at 12 20 43

@eokoneyo eokoneyo requested a review from a team as a code owner January 25, 2024 11:34
Comment on lines 50 to 52
if (cache[backgroundColor]) {
return cache[backgroundColor];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately consumers (not Kibana specifically, but in general) can customize more than just the backgroundColor. They could, for example, also override any or all of the text colors used below, which then would not correctly update per-theme or per-override. So we need to cache/memoize the variables per theme rather than just per background color.

@eokoneyo I spiked out a local attempt at converting this util to a hook with useMemo(): main...cee-chen:eui:code/emotion-perf

Is there any chance you could give it a shot in Kibana and see if it also reduces renders/improves performance similar to what's in your current PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately consumers (not Kibana specifically, but in general) can customize more than just the backgroundColor. They could, for example, also override any or all of the text colors used below, which then would not correctly update per-theme or per-override. So we need to cache/memoize the variables per theme rather than just per background color.

Thanks for providing this additional context, totally makes sense to me. I'll test out your referenced spike.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @cee-chen, I finally got around to trying out the referenced spike, it does offer significant improvement to what the current state is and we get to keep the implementation native to react. see screenshot below;

Screenshot 2024-01-30 at 16 03 50

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woohoo, that's super exciting!! Thank you so much for checking @eokoneyo! How would you like to proceed with this work? If you want, we can cherry-pick my branch into this branch/PR and I can approve and merge. Or alternatively, I can open a new PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cee-chen given we are opting for the react implementation, I'm not sure I see any value in cherry-picking the work you've done into this PR especially that we can use it as is, I'd be happy to review once we have it up!!

Copy link
Contributor

@cee-chen cee-chen Jan 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, I mostly want you to get credit for the commit! It was your impetus/idea after all :) I might take over this PR just to get it merged in if that's cool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally fine by me, I do appreciate the consideration too. Thanks Cee!

@cee-chen cee-chen mentioned this pull request Jan 26, 2024
16 tasks
@cee-chen cee-chen changed the title Avoid recomputing code syntax colors [EuiCode/Block] Avoid recomputing code syntax colors Jan 31, 2024
Copy link
Contributor

@cee-chen cee-chen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to go ahead and merge this in since we've essentially had 2 devs test/look over it. Thanks again for bringing this to our attention Eyo! I'll try to take a look at other similar patterns/usages in EUI in the future.

@cee-chen cee-chen enabled auto-merge (squash) January 31, 2024 20:24
@cee-chen cee-chen force-pushed the feat/return-code-syntax-from-cache-when-possible branch from d7e4b18 to 4010bce Compare January 31, 2024 20:32
@kibanamachine
Copy link

Preview staging links for this PR:

@cee-chen cee-chen merged commit 0abab26 into elastic:main Jan 31, 2024
7 checks passed
@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

@eokoneyo eokoneyo deleted the feat/return-code-syntax-from-cache-when-possible branch February 1, 2024 10:02
jbudz added a commit to elastic/kibana that referenced this pull request Feb 8, 2024
`v92.2.1` ⏩ `v93.0.0`

---

## [`v93.0.0`](https://github.com/elastic/eui/releases/v93.0.0)

**Bug fixes**

- Fixed `EuiTextTruncate` component to clean up timer from side effect
on unmount ([#7495](elastic/eui#7495))

**Breaking changes**

- Removed deprecated `anchorClassName` prop from `EuiPopover`. Use
`className` instead ([#7488](elastic/eui#7488))
- Removed deprecated `buttonRef` prop from `EuiPopover`. Use
`popoverRef` instead ([#7488](elastic/eui#7488))
- Removed deprecated `toolTipTitle` and `toolTipPosition` props from
`EuiContextMenuItem`. Use `toolTipProps.title` and
`toolTipProps.position` instead
([#7489](elastic/eui#7489))
- Removed deprecated internal `setSelection` ref method from
`EuiInMemoryTable` and `EuiBasicTable`. Use the new controlled
`selection.selected` prop API instead.
([#7491](elastic/eui#7491))
- `EuiTourStep`'s `className` and `style` props now apply to the
anchoring element instead of to the popover panel, to match `EuiPopover`
behavior. ([#7497](elastic/eui#7497))
- Convert your existing usages to `panelClassName` and `panelStyle`
respectively instead.

**Performance**

- Improved the amount of recomputed styles being generated by `EuiCode`
and `EuiCodeBlock` ([#7486](elastic/eui#7486))

**CSS-in-JS conversions**

- Converted `EuiSearchBar` to Emotion
([#7490](elastic/eui#7490))
- Converted `EuiEmptyPrompt` to Emotion
([#7494](elastic/eui#7494))
- Added `euiBorderColor` and `useEuiBorderColorCSS` style utilities
([#7494](elastic/eui#7494))

---------

Co-authored-by: Jon <jon@elastic.co>
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
`v92.2.1` ⏩ `v93.0.0`

---

## [`v93.0.0`](https://github.com/elastic/eui/releases/v93.0.0)

**Bug fixes**

- Fixed `EuiTextTruncate` component to clean up timer from side effect
on unmount ([elastic#7495](elastic/eui#7495))

**Breaking changes**

- Removed deprecated `anchorClassName` prop from `EuiPopover`. Use
`className` instead ([elastic#7488](elastic/eui#7488))
- Removed deprecated `buttonRef` prop from `EuiPopover`. Use
`popoverRef` instead ([elastic#7488](elastic/eui#7488))
- Removed deprecated `toolTipTitle` and `toolTipPosition` props from
`EuiContextMenuItem`. Use `toolTipProps.title` and
`toolTipProps.position` instead
([elastic#7489](elastic/eui#7489))
- Removed deprecated internal `setSelection` ref method from
`EuiInMemoryTable` and `EuiBasicTable`. Use the new controlled
`selection.selected` prop API instead.
([elastic#7491](elastic/eui#7491))
- `EuiTourStep`'s `className` and `style` props now apply to the
anchoring element instead of to the popover panel, to match `EuiPopover`
behavior. ([elastic#7497](elastic/eui#7497))
- Convert your existing usages to `panelClassName` and `panelStyle`
respectively instead.

**Performance**

- Improved the amount of recomputed styles being generated by `EuiCode`
and `EuiCodeBlock` ([elastic#7486](elastic/eui#7486))

**CSS-in-JS conversions**

- Converted `EuiSearchBar` to Emotion
([elastic#7490](elastic/eui#7490))
- Converted `EuiEmptyPrompt` to Emotion
([elastic#7494](elastic/eui#7494))
- Added `euiBorderColor` and `useEuiBorderColorCSS` style utilities
([elastic#7494](elastic/eui#7494))

---------

Co-authored-by: Jon <jon@elastic.co>
fkanout pushed a commit to fkanout/kibana that referenced this pull request Mar 4, 2024
`v92.2.1` ⏩ `v93.0.0`

---

## [`v93.0.0`](https://github.com/elastic/eui/releases/v93.0.0)

**Bug fixes**

- Fixed `EuiTextTruncate` component to clean up timer from side effect
on unmount ([elastic#7495](elastic/eui#7495))

**Breaking changes**

- Removed deprecated `anchorClassName` prop from `EuiPopover`. Use
`className` instead ([elastic#7488](elastic/eui#7488))
- Removed deprecated `buttonRef` prop from `EuiPopover`. Use
`popoverRef` instead ([elastic#7488](elastic/eui#7488))
- Removed deprecated `toolTipTitle` and `toolTipPosition` props from
`EuiContextMenuItem`. Use `toolTipProps.title` and
`toolTipProps.position` instead
([elastic#7489](elastic/eui#7489))
- Removed deprecated internal `setSelection` ref method from
`EuiInMemoryTable` and `EuiBasicTable`. Use the new controlled
`selection.selected` prop API instead.
([elastic#7491](elastic/eui#7491))
- `EuiTourStep`'s `className` and `style` props now apply to the
anchoring element instead of to the popover panel, to match `EuiPopover`
behavior. ([elastic#7497](elastic/eui#7497))
- Convert your existing usages to `panelClassName` and `panelStyle`
respectively instead.

**Performance**

- Improved the amount of recomputed styles being generated by `EuiCode`
and `EuiCodeBlock` ([elastic#7486](elastic/eui#7486))

**CSS-in-JS conversions**

- Converted `EuiSearchBar` to Emotion
([elastic#7490](elastic/eui#7490))
- Converted `EuiEmptyPrompt` to Emotion
([elastic#7494](elastic/eui#7494))
- Added `euiBorderColor` and `useEuiBorderColorCSS` style utilities
([elastic#7494](elastic/eui#7494))

---------

Co-authored-by: Jon <jon@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants